<?php
// +----------------------------------------------------------------------
// | 杭州十禾信息科技有限公司
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2015 http://www.shelpe.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: LeePuman <ysyzlsm@163.com>
// +----------------------------------------------------------------------

class AutoDriveV2Model extends AutoDriveBaseModel{

	/**
	 * _evaluateXX()方法中编码的实际意义。
	 * @var array(k=>v)
	 */
	public static $STATUS_DESC = array(
			'0000' => '无明显判断条件',
			
			'0101' => '长期转化率太低',
			'0102' => '长期转化率较低',
			'0103' => '长期转化率很高，排名靠后，价格不是很高',
			'0104' => '短期有连续转化，排名靠后，价格不是很高',
			'0104' => '短期有一次转化，排名靠后，价格中低',
			
			'0201' => '低质量得分，且连续3天没有点击',
			'0202' => '低质量得分，且有PV没点击',
			'0203' => '低质量得分，且低ctr，相关度较低',
			'0204' => '低质量得分，但相关度较高，且单价不高',
			'0205' => '低质量得分，且低ctr，单价较高',
			'0206' => '中质量得分，且ctr很低, 价格很高, 低相似度', 
			'0207' => '中质量得分，且pv不低ctr很低, 价格很高, 中高相似度',
			
			'0301' => '低PV，且排名很后，价格不高',
			'0302' => '低PV，且排名中后，价格中等',
			'0303' => '低PV，且排名不靠前，价格较低',
			'0304' => '低PV，不相关，且低ctr',
			'0305' => '低PV，价格较高, 且低ctr',
			'0306' => '连续一个星期基本无PV',
			'0307' => '3天PV=0，且低质量得分, 相关度不是很高',
			
			'0401' => '低ctr，中低qscore，且中高价格',
			'0402' => '中高ctr，排名靠后，且价格不高',
			'0403' => '低ctr，中高qscore，中低价格，排名很后',
			'0404' => '高ctr，但低PV',
			
			'0501' => '排名中后，且价格较低',
			'0502' => '排名很后，且价格极低',
			
			'0601' => '当前价格高于限价',
			'0602' => '价格很高，中低qscore，没有点击',
			'0603' => '价格很高，中低qscore，PV很低且低点击率',
			
			'0701' => '类目或者产品相似度太低',
	);
	
	// 自动开车关键词维护的价格判定常量
	const NOT_KNOWN_PRICE = 0;
	const XLOW_PRICE = 1;
	const LOW_PRICE = 2;
	const MID_PRICE = 3;
	const HIGH_PRICE = 4;
	
	
	// ---------------------- 自动开车启动部分 ----------------------
	/**
	 * 初始化自动开车初始开车的默认参数。
	 */
	protected function _initStartParams() {
		// 先加载基类的默认参数
		parent::_initStartParams();
		
		// 设置自动开车初始化出价的默认参数. 非默认参数可以通过 setDriveParams()设置.
		// 每个变量的默认值依次为 (智能, 引流, 省油, 广撒网)
		$defaultDriveParams = array(
				'sortSimWeight' => array(0.9, 0.7, 0.9, 1),
				'cutThres' => array(0.15, 0.13, 0.18, 0.2),
				'priceSimWeight' => array(1, 0.7, 0.9, 1),
				'maxPriceRatio' => array(1.4, 1.4, 1.2, 1), // 省油模式的斜率更陡，精准词高价，泛词低价。
				'minPriceRatio' => array(1.0, 1.0, 0.6, 0.4),
			//	'pqrRatioRatio' => array(1, 1.3, 0.8),
				'maxCatePriceRatio' => array(1.8, 1.8, 1.1, 0.8), // 关键词出价/加价时，最高不超过行业平均价格的倍数
				'statDays' => array(3, 3, 3, 4), // 关键词短期表现所考虑的天数
		);
		$priceTypeId = $this->_priceTypeId - 1;
		foreach($defaultDriveParams as $name => $val) {
			$this->_driveParams[$name] = is_array($val) ? $val[$priceTypeId] : $val;
		}
		if($this->_pqProduct['max_expense']>0){
			$this->_driveParams['maxCatePriceRatio']=$this->_driveParams['maxCatePriceRatio']*$this->_pqProduct['max_expense']*0.01;
		}
		return $this;
	}

	/** 
     * 选词出价
     * @param array(string) $existentWords
     * @param int[=0] $numToChoose 如果给定，则选出这么多个词。留空则根据adgroup的容量来定数量。
     * @return array2D
     */
    public function selectWords($existentWords, $numToChoose = 0, $cus_default_price = 0) {
    	$numToChoose = $numToChoose > 0 ? $numToChoose 
    			: ($numToChoose == -1 ? count($this->_cndWords) 
    					: AutoDriveBaseModel::MAX_WORDS_PER_ADGROUP - count($existentWords));
    	/*
		 $maxPrice = (!$this->_pqProduct || $this->_pqProduct['default_price'] == 0) ? AutoDriveBaseModel::DEFAULT_WORD_MAX_PRICE
		: $this->_pqProduct['default_price'];
		*/
    	$dp = $this->_driveParams;
    	// 最大限价优先级： 参数中直接给定 > auto_pro_product_queue > 默认的最大限价
		$maxSetPrice = isset($dp['abs_max_price']) && $dp['abs_max_price'] ? $dp['abs_max_price'] : 
				( $this->_pqProduct  && $this->_pqProduct['default_price'] > 0 
					? $this->_pqProduct ['default_price'] 
					: AutoDriveBaseModel::DEFAULT_WORD_MAX_PRICE );
		$this->_checkData(array('CatWordAvgPrice'), false); // , 'CateStat3Days'
		$maxCatPrice= $dp['maxCatePriceRatio']*$this->_driveData['WordAvgPrice'];
		$maxPrice=$maxSetPrice>$maxCatPrice&&$maxCatPrice>0?$maxCatPrice:$maxSetPrice;
		return $this->setPrice($maxPrice, $numToChoose, $cus_default_price);
	}
	
	/**
	 * 根据开车策略和各项统计数据给关键词出价。
	 * 该出价模式的原则是：先选出至少100个或者$numLeft个词，然后求出这些词的最大和最小出价得分，最大得分的词取最高价，
	 * 最低得分的词取最低价，其他词按得分线性出价。
	 *
	 * @param int $maxPrice 关键词的最高出价. 单位为分.
	 * @param int $numLeft 要取的词的个数
	 * @return 设定好价格的词。  array('word'=>XX, 'max_price'=>NN, 'matchscope'=>NN).
	 */
	protected function setPrice($maxPrice, $numLeft, $cus_default_price = 0) {
		if(!$this->_cndWords) return array();
		 
		$this->_checkData(array('WordTbStats3Days', 'Similarity', 'PQR'), false); // , 'CateStat3Days'
		$tbStats = $this->_driveData['WordTbStats3Days'];
		// 		$similarities = $this->_driveData['Similarity'];
	
		// 默认的取词阈值
		$maxPriceRatio = $this->_driveParams['maxPriceRatio'];
		$minPriceRatio = $this->_driveParams['minPriceRatio'];
	
		// 先选词
		$selectedNum = 0;
		$minSelNum = 20; // 最少选20个词
		$cndSelWords = array();
		$maxPriceScore = 0;
		$minPriceScore = 1;
		foreach($this->_cndWords as $word => $weight) {
			$priceScore = $this->priceScore($word); //$this->priceScore($word);
			if($priceScore > 0 || ($selectedNum < $minSelNum&&isset($this->_driveParams['retAct'])&&$this->_driveParams['retAct']!=1)) {
				if($this->_priceTypeId==4){//经济广撒网模式下，降低热门词的pricescore
					$priceScore=$priceScore/pow($tbStats[$word]['competition'],0.25);
				}
				$cndSelWords[$word] = $priceScore > 0 // $priceScore==0的词是因为数目少于100而被强制选上的，需要重新计算priceScore.
						? $priceScore : $this->_weight($word, $this->_driveParams['priceSimWeight']);
				
				if($priceScore > $maxPriceScore)
					$maxPriceScore = $priceScore;
				if($priceScore < $minPriceScore)
					$minPriceScore = $priceScore;
			}
			
			--$numLeft;
			++$selectedNum;
			
			if($numLeft <= 0)
				break;
		}
		// 出价曲线的斜率. 根据上面所选词的最大和最小得分, 最大和最小允许出价计算得出.
		$slope = $maxPriceScore > $minPriceScore 
				? ($maxPriceRatio - $minPriceRatio) / ($maxPriceScore - $minPriceScore)
				: 0;
		
		// 再出价
		$chosenWords = array();
		foreach($cndSelWords as $word => $priceScore) {
			if($cus_default_price > 0) {
				$price = $cus_default_price;
			} else {
				$price = $slope > 0 
						? ($minPriceRatio + $slope * ($priceScore - $minPriceScore)) * $tbStats[$word]['avg_price']
						: $tbStats[$word]['avg_price'];
				$price = min($maxPrice, max($price, AutoDriveBaseModel::MIN_PRICE));
			}
				
			$chosenWords[$word] = array(
					'word' => $word,
					'max_price' => $price,
					'matchscope' => AutoDriveBaseModel::DEFAULT_MATCHSCOPE,
			);
		}
		
		return $chosenWords;
	}
	
    public function maintainAdgroupKeywords($days = 2) {
		if(!$this->_adgroup)
			throw_exception('还未调用init()初始化adgroup。');

		$userId = $this->_userId;
		$adgroupId = $this->_adgroup['adgroup_id'];
    	 
    	//首先更新一遍当前关键词及其报表
    	$syncMdl = new SyncModel();
    	$syncMdl->syncKeywords($userId, $adgroupId);
    	$this->_getRptKeywordMdl()->syncAdgroupKeywordReport($userId, $this->_adgroup['campaign_id'], $adgroupId);
    	
    	$wordsToDelete = array();
    	$wordsToUpdate = array();
    	
    	// 获取关键词
    	$keywords = $this->_getKeywordMdl()->where(array('adgroup_id'=>$adgroupId))->select(); //获取adgroup所有关键词
    	$keywordIds = array_column($keywords, 'keyword_id'); // array(number)
    	$wordStrs = array_column($keywords, 'word'); // array(string)
    	$this->_driveData['keywordIds'] = $keywordIds; // 在获取统计数据( _checkDataXX() )时需要
    	// 所有用过的词(带权重信息)
    	$rawUsedWords = $this->_getAutoProPqMdl()->where(array( // ->field('used_words')
		    			'product_id' => $this->_pqProduct['product_id'],
		    			'campaign_id' => $this->_pqProduct['campaign_id'])
    			)->getField('used_words');
    	$usedWords = $rawUsedWords ? json_decode($rawUsedWords, true) : null; // 先尝试用json_decode新版本: 保存了词及其权重
		if($usedWords) {
			foreach($wordStrs as $wordStr) 
				$this->_cndWords[$wordStr] = isset($usedWords[$wordStr]) ? $usedWords[$wordStr] : 0;
		} else {
			$this->_cndWords = array_fill_keys($wordStrs, 0);
		}
    	
		if($keywords) {
	    	// 获取词的统计数据
	    	$this->_checkDataWordStats3Days();
	    	if(!$this->_driveData['WordStats3Days']) { // 如果最近3天都没有数据，说明之前暂停了，刚刚重新开启。没必要更新。
				$this->logInfo('最近3天没有数据，没必要更新。');
	    		return false;
	    	}
	    	$this->_checkDataWordStatsXDays(7, 'impressions,ctr,click,pay_count,cpc')	
	    			->_checkDataWordStatsXDays(30, 'click,pay_count', 'summary') 
	    			->_checkDataWordTbStats3Days()
	    			->_checkDataIndustryStats()
	    			->_checkDataCatWordAvgPrice() 	
	    			->_checkDataSimilarity();
	    	// DEBUG
// 	    	$this->logDebug('product similarity:');
// 	    	$this->logDebug(json_encode($this->_driveData['ProdSim']));
// 	    	$this->logDebug('category similarity:');
// 	    	$this->logDebug(json_encode($this->_driveData['CateSim']));
	    	
	    	$this->_initMaintainParams();
	    	$this->_logMaintain();
	    	
	    	// 逐个维护关键词
	    	foreach($keywords as $kid => $keyword){
	    		if(strtotime($keyword['create_time']) <= time() - 2 * 86400) { // 至少要有2天数据
	    			$this->maintainKeyword($keyword, $wordsToUpdate, $wordsToDelete);
	    		}
	    	}
	    	// 提交需要修改/删除的关键词
	    	if(!$this->_driveParams['test']) { // 如果不是测试
		    	$apiMdl = $this->_getApiMdl();
		    	if($wordsToDelete)
		    		$this->_getKeywordMdl()->deleteKeywords($wordsToDelete, $this->_adgroup['campaign_id'], $apiMdl, true);
		    /*	if($wordsToUpdate)
		    		$this->_getKeywordMdl()->updateKeywords($adgroupId, $wordsToUpdate, $apiMdl, true);*/
	    	} else {
	    		$this->logDebug('测试环境, 不提交到直通车.');
	    	}
		} // ~if($keywords)
    		
    	// 添加新词
    	if(!$this->_driveParams['test']) { // 如果不是测试
	    	$this->logDebug('开始添加新词');
	    	if(count($keywords) - count($wordsToDelete) < AutoDriveBaseModel::MAX_WORDS_PER_ADGROUP) {
	    		$this->_cndWords = null; // 清空之前关键词维护时设定的 _cndWords.
	    		$wordavgprice=$this->_driveData['WordAvgPrice'];
	    		$words=$this->_driveData['CatTopWord'];
	    		$avcomp=$this->_driveData['CatTopWordAvgCompe'];
	    		$this->_driveData = null; // 清空之前关键词维护时的数据.
	    		$this->_driveData['WordAvgPrice']=$wordavgprice;
	    		$this->_driveData['CatTopWord']=$words;
	    		$this->_driveData['CatTopWordAvgCompe']=$avcomp;
	    		try{
	    			$this->_initStartParams()
			    		->setDriveParams( array('cutThres' => $this->_driveParams['cutThres'] - 0.05) )
			    		->addProKeywords($wordStrs, false, 0);
	    		} catch (Exception $e) {
					// log the error
					$msg=$e->getMessage();
					$this->logInfo('addProKeywords error: '.$msg);
				}	
	    	}
    	}
    	
    	return $wordsToUpdate;
    }
    
    protected function maintainKeyword(&$keyword, &$wordsToUpdate, &$wordsToDelete,
    		$stat3Day = null, $stat7Day = null, $tbStat3Day = null, $cateStat = null) { // 这几个参数只是为了跟AutoDriveBaseModel::maintainKeyword()一致。
    	$dd = $this->_driveData;
    	$dp = $this->_driveParams;
    	
    	$keywordId = $keyword['keyword_id'];
    	
    	$zeroStat = AutoDriveBaseModel::$ZERO_STAT;
    	$stat3Day = isset($dd['WordStats3Days'][$keywordId]) ? $dd['WordStats3Days'][$keywordId] : $zeroStat;
    	$stat7Day = isset($dd['WordStats7Days'][$keywordId]) ? $dd['WordStats7Days'][$keywordId] : $zeroStat;
    	$stat30Day = isset($dd['WordStats30Days'][$keywordId]) ? $dd['WordStats30Days'][$keywordId] : $zeroStat;
    	$tbStat3Day = $dd['WordTbStats3Days'][$keyword['word']];
    	$industryStat = $dd['IndustryStats'];
    	$sml = $dd['Similarity'][$keyword['word']];
    	
    	$oriPrice = $keyword['max_price'];
    	// 每次改价为全网平均价格的的10%, 但不低于10分, 不超过50分
    	$changePrice = max(min($tbStat3Day['avg_price'] * $dp['changePriceRatio'], $dp['maxChangePrice']), $dp['minChangePrice']); 
    	
    	// 该关键词最大取价。取以下值的最小者: 行业平均出价*X, (取消该词的平均出价*Y), 用户给定的限价, 以及系统设定的最高价格。
    	$cateAvgPrice =  $dd['WordAvgPrice']; 
    	$maxPrice = $this->_pqProduct  && $this->_pqProduct['default_price'] > 0 
					? $this->_pqProduct ['default_price'] 
					: AutoDriveBaseModel::DEFAULT_WORD_MAX_PRICE ;
    	$maxPrice = $cateAvgPrice>0?min($maxPrice, $dp['maxCatePriceRatio'] * $cateAvgPrice):$maxPrice;
    	
    	// 维护关键词
    	$autoLog = array('avg_price' => ($stat3Day['click'] > 0 ? round($stat3Day['cpc'] * 100) : round($oriPrice))); //'avg_price' => $stat3d['click'] > 0 ? round($stat3d['avg_price']) : round($keyword['max_price']),
		$this->_evaluateAvgpos($keyword, $autoLog, $stat3Day, $sml, $cateAvgPrice) // avgpos
				->_evaluateSim($keyword, $autoLog)
				->_evaluateCvr($keyword, $autoLog, $stat3Day, $stat7Day, $stat30Day, $industryStat['trend_cvr_seller'], $cateAvgPrice) // 1. cvr
    			->_evaluateCtr($keyword, $autoLog, $stat3Day, $tbStat3Day, $sml, $cateAvgPrice) // 4. ctr
    			->_evaluateQscore($keyword, $autoLog, $stat3Day, $tbStat3Day, $sml, $cateAvgPrice) // 2. qscoce
    			->_evaluatePv($keyword, $autoLog, $stat3Day, $stat7Day, $tbStat3Day, $sml, $cateAvgPrice) // 3. pv
    			->_evaluatePrice($keyword, $autoLog, $stat3Day, $tbStat3Day, $changePrice, $maxPrice)
				->_handleEvaluationRes($keyword, $autoLog, $stat3Day,$changePrice, $maxPrice); // 处理结果
    	$blacklist=array("新款");
    	foreach($blacklist as $word)
    		if($keyword['word']==$word) {
    			$keyword['max_price'] = -1;
    	}
    	if($keyword['max_price'] == -1) { // 删除
    		$wordsToDelete[] = $keywordId;
    	} else if($keyword['max_price'] != $oriPrice) { // 改价
    		// debug
    		$this->logDebug('update keyword: ' . $keyword . ' - ' . $keyword['word'] . ' : ' . $oriPrice . ' => ' . $keyword['max_price']);
    		$wordsToUpdate[$keywordId] = array(
    				'word' => $keyword['word'],
    				'keyword_id' => $keywordId,
    				'max_price'  => $keyword['max_price'],
    				'matchscope' => $keyword['matchscope'] ? $keyword['matchscope'] : AutoDriveBaseModel::DEFAULT_MATCHSCOPE
    		);
    	} //else {} // 不变
    	 
    	$this->_logMaintain($keyword, $autoLog);
    }

    /**
     * 初始化关键词维护各项参数
     */
    protected function _initMaintainParams() {
    	// 关键词维护各项参数 array( priceTypeId => ratio )，依次为1:智能；2：引流；3：省油,4:广撒网。
    	$defaultParams = array(
    			'xlowCatePriceRatio' => array(1=>0.8, 2=>0.8, 3=>0.4,4=>0.3), // 特低价比例。相对于行业（或者类目）平均出价（例如5分）
    			'lowCatePriceRatio' => array(1=>1, 2=>1, 3=>0.6,4=>0.4), // 低价比例。相对于行业（或者类目）平均出价
    			'midCatePriceRatio' => array(1=>1.3, 2=>1.3, 3=>0.8,4=>0.6), // 中等价格比例。相对于行业（或者类目）平均出价
    			'highCatePriceRatio' => array(1=>1.6, 2=>1.6, 3=>1,4=>0.7), // 高价比例。相对于行业（或者类目）平均出价
    		/*	'xlowWordPriceRatio' => array(1=>0.4, 2=>0.4, 3=> 0.3), //  超低价格比例。相对于关键词自己的平均出价
    			'lowWordPriceRatio' => array(1=>0.7, 2=>0.7, 3=> 0.5), // 低价格比例。相对于关键词自己的平均出价
    			'midWordPriceRatio' => array(1=>0.9, 2=>1.0, 3=>0.7), // 高价比例。相对于关键词自己的平均出价
    			'highWordPriceRatio' => array(1=>1.1, 2=>1.3, 3=>0.9), // 高价比例。相对于关键词自己的平均出价*/
    		//	'maxWordPriceRatio' => array(1=>1.3, 2=>1.5, 3=>1.1), // 关键词加价时，最高不超过该关键词的平均价格的倍数
    			'lowPvRatio' => array(1=>1, 2=>1, 3=>1, 4=>0.3), // <此比值*('tbStat['pv']/'tbStat['competition'])的，为低pv。
    			'xtopPos' => array(1=>5, 2=>6, 3=>7, 4=>7), // <=此值的位置为极高位置
    			'topPos' => array(1=>17, 2=>17, 3=>26, 4=>26), // <=此值的位置为高位置
    			'midPos' => array(1=>43, 2=>43, 3=>52, 4=>52), // <=此值的位置为中位置
    			'lowPos' => array(1=>82, 2=>82, 3=>95, 4=>95), // >此值的位置为低位置
    			
    			'lowProdSimThres' => 0.05,	// 低于该标题相似度的词会被删除
    			'lowCateSimThres' => 0.2,	// 低于该类目相似度的词会被删除
    			'lowSimThres'  => 0.15,		// < 此值的综合相似度，为低相似度。
    			'highSimThres' => 0.2,		// >=此值的综合相似度，为高相似度。
    			'xhighSimThres' => 0.35,	// >=此值的综合相似度，为超高相似度。（精准词） TODO handle this specially???
    			'highQscore'   => 8,		// >=此值的QScore，为高QScore。
    			'midQscore'    => 6,		
    			'lowQscore'    => 3,		// <=此值的QScore，为低QScore。
    			'lowCtrRatio'  => 0.5,      // < 此比值*该词平均ctr的，为低ctr。
    			'highCtrRatio' => array(1=>2, 2=>2, 3=>2,4=>3),        // > 此比值*该词平均ctr的，为高ctr。
    			'absXLowPv' => array(1=>50, 2=>50, 3=>15,4=>5), // < 此pv的, 为极低pv
    			'absLowPv' => array(1=>200, 2=>200, 3=>50,4=>15), // < 此pv的, 为低pv
    			'PvClick' => array(1=>1.5, 2=>1.5, 3=>1,4=>1), // 此值为应有点击数量，用来判读pv是否足够做出判读
    		//	'avgCatePriceRatio' => 1, // 行业平均取价为计算得出值的倍数
    			'changePriceRatio' => 0.1, // 每次改价幅度
    			'maxChangePrice' => 50, // 每次改价不超过的阈值(分)
    			'minChangePrice' => 10, // 每次改价不低于的阈值(分)
    	);
    	foreach($defaultParams as $paramName => $paramVal) {
    		$this->_driveParams[$paramName] = is_array($paramVal) ? $paramVal[$this->_priceTypeId] : $paramVal;
    	}
    	return $this;
    }
    
    /**
     * 判断该关键词的平均点击花费所在的价位.
     * 
     * @param array(k=>v) $keyword 要判断的关键词
     * @param int[=0] $type 如果给定, 判断关键词是否满足该价位, 否则直接给出关键词的价位.  
     * @return boolean|int 如果给定$type, 返回true|false; 否则返回关键词所在价位(1~4)
     */
    protected function _checkPrice($keyword, $type = self::NOT_KNOWN_PRICE) {
    	$dd = $this->_driveData;
    	$dp = $this->_driveParams;
    	$stat3Day = $dd['WordStats3Days'][$keyword['keyword_id']];
    	$tbStat3Day = $dd['WordTbStats3Days'][$keyword['word']];
    	$avgCatePrice = $dd['WordAvgPrice'];
    	$cpc = $stat3Day['click'] > 0 ? $stat3Day['cpc'] * 100 : $keyword['max_price'];
    	if($type > 0) {
    		switch($type) {
    			case self::XLOW_PRICE:
    				return $cpc <= $dp['xlowCatePriceRatio'] * $avgCatePrice;// || $cpc <= $dp['xlowWordPriceRatio'] * $tbStat3Day['avg_price'];
    			case self::LOW_PRICE:
    				return $cpc <= $dp['lowCatePriceRatio'] * $avgCatePrice;// || $cpc <= $dp['lowWordPriceRatio'] * $tbStat3Day['avg_price'];
    			case self::MID_PRICE:
//     				return ($cpc > $dp['lowCatePriceRatio'] * $avgCatePrice && $cpc > $dp['lowWordPriceRatio'] * $tbStat3Day['avg_price'])
//     						&& ($cpc <= $dp['highCatePriceRatio'] * $avgCatePrice || $cpc <= $dp['highWordPriceRatio'] * $tbStat3Day['avg_price']);
    				return $cpc <= $dp['midCatePriceRatio'] * $avgCatePrice;// || $cpc <= $dp['midWordPriceRatio'] * $tbStat3Day['avg_price'];
    			case self::HIGH_PRICE:
    				return $cpc > $dp['highCatePriceRatio'] * $avgCatePrice;// && $cpc > $dp['highWordPriceRatio'] * $tbStat3Day['avg_price'];
    		}
    	} else {
    		if($cpc <= $dp['xlowCatePriceRatio'] * $avgCatePrice)// || $cpc <= $dp['xlowWordPriceRatio'] * $tbStat3Day['avg_price'])
    			return self::XLOW_PRICE;
    		elseif($cpc <= $dp['lowCatePriceRatio'] * $avgCatePrice)// || $cpc <= $dp['lowWordPriceRatio'] * $tbStat3Day['avg_price'])
    			return self::LOW_PRICE;
    		elseif($cpc > $dp['highCatePriceRatio'] * $avgCatePrice)// && $cpc > $dp['highWordPriceRatio'] * $tbStat3Day['avg_price'])
    			return self::HIGH_PRICE;
    		else
    			return self::MID_PRICE;
    	}
    }
    /**
     * 添加自动维护log.
     * @param number $type 0: 关键词3天表现; 1: 行业数据
     */
    protected function _logMaintain($keyword = null, $autoLog = null) {
    	$dd = $this->_driveData;
    	if($keyword) {
    		$keywordId = $keyword['keyword_id'];
    		$stat3d = $dd['WordStats3Days'][$keywordId];
    		$stat30d = $dd['WordStats30Days'][$keywordId];
    		$sim = $dd['Similarity'][$keyword['word']];
    		
    		$autoLogFull = array(
    				'keyword_id' => $keyword['keyword_id'],
    				'date' => date('Y-m-d'),
    				'pv' => round($stat3d['impressions']),
    				'click' => round($stat3d['click'], 1),
    				'ctr' => round($stat3d['ctr'] * 100),
    				'cvr' => $stat30d['click'] > 0 ? round(100 * $stat30d['pay_count'] / $stat30d['click']) : 0,
    				'cvr2' => $stat3d['click'] > 0 ? round(100 * $stat3d['pay_count'] / $stat3d['click']) : 0,
    				'qscore' => $keyword['qscore'],
    				'avgpos' => round($stat3d['avgpos']),
//     				'avg_price' => $stat3d['click'] > 0 ? round($stat3d['avg_price']) : round($keyword['max_price']),
    				'avg_price' => $autoLog['avg_price'],
    				'similarity' => round($sim * 100),
    				'action' => $autoLog['action'] ? $autoLog['action'] : '000000',
    		);
    		M('auto_maintain_log')->add($autoLogFull, null, true);
    	} else { // 每次维护的时候其中一行记录行业数据，该行的keyword_id不是关键词id，而是推广组id。
	    	$adgroupId = $this->_adgroup['adgroup_id'];
	    	$industryData = $dd['IndustryStats'];
	    	$autoLogFull = array(
	    			'keyword_id' => $adgroupId,
	    			'date' => date('Y-m-d'),
	    			'cvr' => round($industryData['trend_cvr_seller'] * 100),
	    			'avg_price' => round($dd['WordAvgPrice']),
	    	);
	    	M('auto_maintain_log')->add($autoLogFull, null, true);
    	}
    	return $this;
    } 
    
    /**
     * 根据结果处理关键词. 主要是判断降价/加价是否超过限值. 
     * 将实际需要进行的操作记录到$autoLog['action']最后一位.
     * 
     * @param array(k=>v) $keyword
     * @param array(k=>v) $autoLog 操作记录，所需字段为status。
     * @param int $changePrice 加/降价量(分)
     * @param int $maxPrice 最高可能的价格(分)
     */
    protected function _handleEvaluationRes(&$keyword, &$autoLog,$stat3Day, $changePrice, $maxPrice) {
    	if(!$autoLog['action']) 
    		return $this;
    	$dp = $this->_driveParams;
    	$checkRres = substr($autoLog['action'], -1);
    	switch($checkRres) {
    		case AutoMaintainLogActions::NO_CHANGE:
    			$autoLog['action'] .= AutoMaintainLogActions::NO_CHANGE;
    			break;
    		case AutoMaintainLogActions::DEL_WORD:
    			$keyword['max_price'] = -1;
    			$autoLog['action'] .= AutoMaintainLogActions::DEL_WORD;
    			break;
    		case AutoMaintainLogActions::INC_PRICE:
    			if($keyword['max_price'] >= $maxPrice) {
    				$autoLog['action'] .= AutoMaintainLogActions::NO_CHANGE;
    			}else if($stat3Day['avgpos']>$dp['xtopPos']||$stat3Day['avgpos']==0){//检查是否排名已经很靠前
    				if($keyword['max_price'] + $changePrice > $maxPrice) {
    					$keyword['max_price'] = $maxPrice;
    					$autoLog['action'] .= AutoMaintainLogActions::INC_PRICE_NOT_FULL;
    				} else {
    					$keyword['max_price'] += $changePrice;
    					$autoLog['action'] .= AutoMaintainLogActions::INC_PRICE;
    				}
    			}else{
    				$autoLog['action'] .= AutoMaintainLogActions::NO_CHANGE;
    			}
    			
    			break;
    		case AutoMaintainLogActions::DEC_PRICE:
    			if($keyword['max_price'] <= parent::MIN_PRICE) {
    				$autoLog['action'] .= AutoMaintainLogActions::NO_CHANGE;
    			} else if($keyword['max_price'] - $changePrice < parent::MIN_PRICE) {
    				$keyword['max_price'] = parent::MIN_PRICE;
    				$autoLog['action'] .= AutoMaintainLogActions::DEC_PRICE_NOT_FULL;
    			} else {
    				$keyword['max_price'] -= $changePrice;
    				$autoLog['action'] .= AutoMaintainLogActions::DEC_PRICE;
    			}
    			break;
    		case AutoMaintainLogActions::DEC_PRICE_TO_MAX_ALLOWED;
    			$keyword['max_price']  = $maxPrice;
    			$autoLog['action'] .= AutoMaintainLogActions::DEC_PRICE_TO_MAX_ALLOWED;
    			break;
    		default:
    			break;
    	}
    	return $this;
    }
    
    /**
     * 检查相似度。
     * 一般说来在addProKeywords的时候已经通过相似度过滤了。不过最刚开始的版本因为计算相似度错误，会造成
     * 低相似度的词被误加进来，因而需要在维护的时候检查。
     * 
     * @param array(k=>v) $keyword
     * @param array(k=>v) $autoLog
     * @return AutoDriveV2Model
     */
    protected function _evaluateSim($keyword, &$autoLog) {
    	$tbStats = $this->_driveData['WordTbStats3Days'][$keyword['word']];
    	$cateStats = $this->_driveData['WordCateStats3Days'][$keyword['word']];
    	$cateSim = $this->_driveData['CateSim'][$keyword['word']];
    	$prodSim = $this->_driveData['ProdSim'][$keyword['word']];
    	$dp = $this->_driveParams;
    	
    	if(($tbStats['pv']>0&&$cateStats['pv']>0&&$cateSim < $dp['lowCateSimThres']) || $prodSim < $dp['lowProdSimThres']) {
    		$autoLog['action'] = '0701' . AutoMaintainLogActions::DEC_PRICE;
    	}
    	return $this;
    }
    
    /**
     * 根据给定的某关键词的其转化率，判断对其应该进行的操作。结果记录在$autoLog['action']中.
     * @param array(k=>v) $keyword
     * @param array(k=>v) $autoLog
     * @param array(k=>v) $stat3Day （平均值）.
     * @param array(k=>v) $stat30Day （合计值）.
     * @param float $industryCvr 行业平均转化率(小数)
     * @param float $cateAvgPrice 行业/类目平均出价(分)
     * @return AutoDriveV2Model
     */
    protected function _evaluateCvr($keyword, &$autoLog, $stat3Day, $stat7Day, $stat30Day, $industryCvr, $cateAvgPrice) {
    	if($autoLog['action'])
    		return $this;

    	$dp = $this->_driveParams;
    	 
    	
    	$delCreThres = array(1 => 2, 2 => 2, 3 => 1.5,4=>0.4); // 要删除某个词所需要的点击可信度。三个元素分别对应（智能、引流、节油），下同。
    	$delCvrThres = array(1 => 0.35, 2 => 0.35, 3 => 0.4,4=>0); // 低于转化率阈值时，删词。
    	$decCreThres = array(1 => 1.5, 2 => 1.5, 3 => 1.0,4=>0.2); // 要降价某个词所需要的点击可信度。
    	$decCvrThres = array(1 => 1, 2 => 1, 3 => 1,4=>1); // 低于转化率阈值时，降价。
    	$incCreThres = array(1 => 1.5, 2 => 2.0, 3 => 1.5,4=>1); // 要加价某个词所需要的点击可信度。
    	$incCvrThres = array(1 => 3, 2 => 3, 3 => 4,4=>5); // 高于转化率阈值时，加价。
//     	$lowPosThres = array(1 => 28, 2 => 28, 3 => 40);
    	
    	$priceType = $this->_priceTypeId;
    
    	if($stat3Day['click'] > 0 && $industryCvr > 0 && $stat30Day && $stat30Day['click'] > 0) {
    		$cre = 0;
    		$cvr = 0;
    		if(!empty($stat7Day) && $stat7Day['click'] * $industryCvr >=$delCreThres[$priceType]) {
    			$cre = $stat7Day['click'] * $industryCvr;	// 理论上应该有的成交笔数
    			$cvr = $stat7Day['pay_count'] / $cre;		// 转化率比率=实际成交笔数/理论成交笔数
    		} else {
    			$cre = $stat30Day['click'] * $industryCvr;
    			$cvr = $stat30Day['pay_count'] / $cre;
    		}
    		
    		// 长期转化率太低，删除
    		if($cre > $delCreThres[$priceType] && $cvr < $delCvrThres[$priceType]) {
    			$autoLog['action'] = '0101' . AutoMaintainLogActions::DEL_WORD;
    		// 长期转化率较低，降价
    		} else if($cre > $decCreThres[$priceType] && $cvr < $decCvrThres[$priceType]) {
    			$autoLog['action'] = '0102' . AutoMaintainLogActions::DEC_PRICE;
    		// 长期转化率很高，排名中后，且价格中高，加价
    		} else if($cre > $incCreThres[$priceType] && $cvr > $incCvrThres[$priceType]) {
    			if($stat3Day['avgpos'] >= $dp['topPos']
	    				&& !$this->_checkPrice($keyword, self::HIGH_PRICE)) {
	    			$autoLog['action'] = '0103' . AutoMaintainLogActions::INC_PRICE;
    			}
    		} else {
    			// 检查是否短期连续有转化
    			$rptMdl = $this->_getRptKeywordMdl();
    			// 获取序列数据。格式为： 
// 				array(1) {
// 				  ["成交笔数"] => array(6) {
// 				    [0] => array(2) {
// 				      [0] => int(1374105600000)
// 				      [1] => int(0)
// 				    }
// 				    [1] => array(2) {
// 				      [0] => int(1374192000000)
// 				      [1] => int(0)
// 				    }
//					...
// 				   }
// 				  }
    			$payCntSeriel2D = $rptMdl->getSeriesStats(
    					$this->_userId, 'keyword_id', 
    					array($keyword['keyword_id']), 'pay_count', 
    					date('Y-m-d', time() - 3 * 86400), date('Y-m-d', time() - 86400));
    			$payCntSeriel = array_pop($payCntSeriel2D);
    			$cvrDays = 0; // 有转化的天数
    			foreach($payCntSeriel as $payCnt) {
    				if($payCnt[1] > 0)
    					++$cvrDays;
    			}
    			
    			// 短期有连续转化，价格不是很高
    			if($cvrDays >= 2 && $stat3Day['avgpos'] >= $dp['midPos']
		    			&& !$this->_checkPrice($keyword, self::HIGH_PRICE)) {
	    			$autoLog['action'] = '0104' . AutoMaintainLogActions::INC_PRICE;
	    		// 短期有一次转化，价格中低
    			} else if($cvrDays == 1 && $stat3Day['avgpos'] >= $dp['midPos']
		    			&& $this->_checkPrice($keyword, self::LOW_PRICE)) {
    				$autoLog['action'] = '0105' . AutoMaintainLogActions::INC_PRICE;
    			}
    		}
    		// 短期有高转化，或者中等转化并且价格不是很高
//     		} else if($cvr > $incCvrThres[$priceType] || 
//     				($cvr > $decCvrThres[$priceType] && !$this->_checkPrice($keyword, self::HIGH_PRICE))
//     				&& $$stat30Day['avgpos'] > $dp['topPos']){
//     			$autoLog['action'] = '0104' . AutoMaintainLogActions::NO_CHANGE;
//     		}
    	}
    	return $this;
    }

    /**
     * 根据ctr主判
     * @param array(k=>v) $keyword 关键词
     * @param array(k=>v) $autoLog 操作log
     * @param array(k=>v) $stat3Day 该关键词3天表现（平均值）
     * @param array(k=>v) $tbStat3Day 该关键词3天淘宝全网表现（平均值）.
     * @param float $sml 关键词的综合相关度
     * @param float $cateAvgPrice 行业/类目平均出价(分)
     * @return AutoDriveV2Model
     */
    protected function _evaluateCtr($keyword, &$autoLog, $stat3Day, $tbStat3Day, $sml, $cateAvgPrice) {
    	if($autoLog['action'])
    		return $this;
    
    	$dp = $this->_driveParams;
    	 
    	// 有足够多的pv来进行判断。pv需大于1.5个点击所需的期望pv, 这样置信度较高 TODO 也可以多考虑几天的ctr。
    	if($stat3Day['impressions'] >= $dp['PvClick']*100 / $tbStat3Day['ctr']) {
    		// 低ctr
    		if($stat3Day['ctr'] < $dp['lowCtrRatio'] * $tbStat3Day['ctr']) {
    			// 中高qscore，中低价格，排名很后 -> 加价
    			/*if( ($keyword['qscore'] >= $dp['midQscore'] || $sml >= $dp['highSimThres'])
    					&& $stat3Day['avgpos'] >= $dp['lowPos'] 
    					&& !$this->_checkPrice($keyword, self::HIGH_PRICE)) {
    				$autoLog['action'] = '0403' . AutoMaintainLogActions::INC_PRICE;
    			// 中低qscore, 中高价格 -> 删除
    			} else*/ if( ($keyword['qscore'] < $dp['midQscore'] && $sml < $dp['lowSimThres'])
		    			&& !$this->_checkPrice($keyword, self::MID_PRICE)) {
    				$autoLog['action'] = '0401' . AutoMaintainLogActions::DEL_WORD;
    			}
    		// 高ctr，排名靠后，且价格不高 -> 加价
    		} else if($stat3Day['ctr'] > $dp['highCtrRatio'] * $tbStat3Day['ctr']
		    		&& $stat3Day['avgpos'] > $dp['midPos']
		    		&& !$this->_checkPrice($keyword, self::HIGH_PRICE)) {
    			$autoLog['action'] = '0402' . AutoMaintainLogActions::INC_PRICE;
    		}
    	} else if($tbStat3Day['ctr'] > 0 && $stat3Day['ctr'] > $dp['highCtrRatio'] * $tbStat3Day['ctr'] // ctr较高但pv较低，说明是冷门词
    			&& ($stat3Day['avgpos'] > $dp['topPos'] || ($stat3Day['impressions'] < $dp['absLowPv'] && $stat3Day['avgpos'] > $dp['xtopPos']))&&$this->_checkPrice($keyword, self::MID_PRICE) ) { 
    		$autoLog['action'] = '0404' . AutoMaintainLogActions::INC_PRICE;
    	}
    	 
    	return $this;
    }
    
    /**
     * 根据qscore主判.
     * @param array(k=>v) $keyword 关键词
     * @param array(k=>v) $autoLog 操作log
     * @param array(k=>v) $stat3Day 该关键词3天表现（平均值）.
     * @param array(k=>v) $tbStat3Day 该关键词3天淘宝全网表现（平均值）.
     * @param float $sml 关键词的综合相关度
     * @param float $cateAvgPrice 行业/类目平均出价(分)
     */
    protected function _evaluateQscore($keyword, &$autoLog, $stat3Day, $tbStat3Day, $sml, $cateAvgPrice) {
    	if($autoLog['action'])
    		return $this;

    	$dp = $this->_driveParams;
    	$createTime = strtotime($keyword['create_time']);
    	
    	// 低质量得分
    	if($keyword['qscore'] <= $dp['lowQscore']&&$sml <= $dp['lowSimThres']) {
    		// 连续3天没有点击(创建超过7天) //，且单价较高
    		if($createTime <= time() - 7 * 86400 && $stat3Day['click'] == 0) { // && $keyword['max_price'] > $cateAvgPrice
    			$autoLog['action'] = '0201' . AutoMaintainLogActions::DEL_WORD;
    		// 平均每天超过170个pv(3天超过500个), 但是基本没有点击。【在_evaluateCtr()中已经考虑了】
//     		} elseif($stat3Day['impressions'] > 170 && $stat3Day['ctr'] <= $tbStat3Day['ctr'] * $dp['lowCtrRatio']) { 
//     			$autoLog['action'] = '0202' . AutoMaintainLogActions::DEL_WORD;
    		// 相关度较低
    		} elseif($sml < $dp['lowSimThres'] 
    				&& $stat3Day['ctr'] < $dp['lowCtrRatio'] * $tbStat3Day['ctr']) { 
    			$autoLog['action'] = '0203' . AutoMaintainLogActions::DEL_WORD;
    		// 相关度较高，有点击且单价不高
    		} elseif($sml >= $dp['highSimThres'] && $stat3Day['click'] > 0 
    				&& $this->_checkPrice($keyword, self::LOW_PRICE)) {
    			$autoLog['action'] = '0204' . AutoMaintainLogActions::INC_PRICE;
    		// 价格较高
    		} elseif(!$this->_checkPrice($keyword, self::MID_PRICE)
    				&& $stat3Day['ctr'] < $dp['lowCtrRatio'] * $tbStat3Day['ctr'] ) {
    			$autoLog['action'] = '0205' . AutoMaintainLogActions::DEL_WORD;
    		}
    	// 中质量得分，且pv不低ctr很低, 价格很高
    	} else if( $keyword['qscore'] < $dp['highQscore'] 
    			&& $stat3Day['ctr'] <= $dp['lowCtrRatio'] * $tbStat3Day['ctr'] 
    			&& $this->_checkPrice($keyword, self::HIGH_PRICE) &&$stat3Day['impressions'] > $dp['absLowPv']) {
    		// 中低相似度
    	/*	if($sml < $dp['highSimThres']) {
    			$autoLog['action'] = '0206' . AutoMaintainLogActions::DEL_WORD;
    		// 高相似度
    		} else {*/
    			$autoLog['action'] = '0207' . AutoMaintainLogActions::DEC_PRICE;
    		
    	}
    	
    	return $this;
    }
    
    /** 
     * 根据PV主判
     * @param array(k=>v) $keyword 关键词
     * @param array(k=>v) $autoLog 操作log
     * @param array(k=>v) $stat3Day 该关键词3天表现（平均值）.
     * @param array(k=>v) $tbStat3Day 该关键词3天淘宝全网表现（平均值）.
     * @param float $sml 关键词的综合相关度
     * @param float $cateAvgPrice 行业/类目平均出价(分)
     * @return AutoDriveV2Model
     */
    protected function _evaluatePv($keyword, &$autoLog, $stat3Day, $stat7Day, $tbStat3Day, $sml, $cateAvgPrice) {
    	if($autoLog['action'])
    		return $this;

    	$dp = $this->_driveParams;
    	
    	// 高pv 但是低点击
    	/* if($stat3Day['impressions'] > 170 && $stat3Day['ctr'] < 0.2) {
    		 
    	// 低pv（日平均pv低于15，或者低于该期望值）。
    	} else  */
    	
    	// 连续一个星期基本无PV,且价格较高
    	if((strtotime($keyword['create_time']) < time() - 7 * 86400) && $stat7Day['impressions'] < 1&&$this->_checkPrice($keyword, self::HIGH_PRICE)) {
    		$autoLog['action'] = '0306' . AutoMaintainLogActions::DEL_WORD;
    	// 3天内低PV
    	} else if($stat3Day['impressions'] < $dp['absXLowPv'])/* || 
    			$stat3Day['impressions'] < $dp['lowPvRatio'] * $tbStat3Day['pv'] / $tbStat3Day['competition'])*/ {
    		// PV=0，且低质量得分
    		if($stat3Day['impressions'] == 0 && $keyword['qscore'] <= $dp['lowQscore'] && $sml < $dp['lowSimThres']) {
    				$autoLog['action'] = '0307' . AutoMaintainLogActions::DEL_WORD;
    		// 相关
    		} else if($keyword['qscore'] > $dp['midQscore'] || $sml >= $dp['highSimThres']) {
    			
    			//if($sml >= $dp['lowSimThres']) {
// 	    			if($stat3Day['ctr'] > $dp['lowCtrRatio'] * $tbStat3Day['ctr']
// 	    					&& $stat3Day['avgpos'] > $dp['midPos']
// 			    			&& !$this->_checkPrice($keyword, self::HIGH_PRICE) ) { 
// 	    			}
    				// 排名很后，且价格较低 -> 加价
    				if( ($stat3Day['avgpos'] == 0 || $stat3Day['avgpos'] > $dp['lowPos'])
    						&& $this->_checkPrice($keyword, self::LOW_PRICE)) {
    					$autoLog['action'] = '0301' . AutoMaintainLogActions::INC_PRICE;
			    	// 排名中后，且价格中等 -> 加价
    				} else if($stat3Day['avgpos'] > $dp['midPos'] && $this->_checkPrice($keyword, self::MID_PRICE)) {
			    		$autoLog['action'] = '0302' . AutoMaintainLogActions::INC_PRICE;
			   		// 排名不靠前, 且价格较低 -> 加价
			    	} else if($stat3Day['avgpos'] > $dp['topPos'] && $this->_checkPrice($keyword, self::LOW_PRICE)) { 
			    		$autoLog['action'] = '0303' . AutoMaintainLogActions::INC_PRICE;
			    	}
    			//}
		    // 不相关, 且低ctr
    		} else if($sml < $dp['lowSimThres']&&$keyword['qscore'] <= $dp['lowQscore'] && $stat3Day['ctr'] <= $dp['lowCtrRatio'] * $tbStat3Day['ctr']) {
    			$autoLog['action'] = '0304' . AutoMaintainLogActions::DEL_WORD;
    		// 价格较高, 且低ctr TODO 这个需要确认
    		}/* else if( !$this->_checkPrice($keyword, self::MID_PRICE)
    		 		&& $stat3Day['ctr'] <= $dp['lowCtrRatio']*$tbStat3Day['ctr']) {
    			$autoLog['action'] = '0305' . AutoMaintainLogActions::DEL_WORD;
    		} */
    	}
    	    	
    	return $this;
    }

    /**
     * 根据排名主判
     * @param array(k=>v) $keyword 关键词
     * @param array(k=>v) $autoLog 操作log
     * @param array(k=>v) $stat3Day 该关键词3天表现（平均值）
     * @param float $sml 关键词的综合相关度
     * @param float $cateAvgPrice 行业/类目平均出价(分)
     * @return AutoDriveV2Model 
     */
    protected function _evaluateAvgpos($keyword, &$autoLog, $stat3Day, $sml, $cateAvgPrice) {
    	if($autoLog['action'])
    		return $this;
    	
    	$dp = $this->_driveParams;
    	
    	// 价格低，且排名中后 -> 加价
    	if($this->_checkPrice($keyword, self::LOW_PRICE) 
    			&& ($stat3Day['avgpos'] == 0 || $stat3Day['avgpos'] >= $dp['lowPos'])
    			&& $keyword['qscore'] > $dp['lowQscore'] && $sml > $dp['lowSimThres'] ) { 
    		$autoLog['action'] = '0501' . AutoMaintainLogActions::INC_PRICE;
   		// 价格极低, 且排名很后 -> 加价
    	} else if($this->_checkPrice($keyword, self::XLOW_PRICE) 
    			&& ($stat3Day['avgpos'] == 0 || $stat3Day['avgpos'] >= $dp['midPos'])
    			&& $keyword['qscore'] > $dp['lowQscore'] && $sml > $dp['lowSimThres'] ) {
    		$autoLog['action'] = '0502' . AutoMaintainLogActions::INC_PRICE;
    	}
    	
    	return $this;
    }
    
    /**
     * 当前CPC或出价超过当前模式的最高限价。比如从引流模式调至省油模式时，会产生大量这样的词。
     * 
     * @param array(k=>v) $keyword 关键词
     * @param array(k=>v) $autoLog 操作log
     * @param array(k=>v) $stat3Day 该关键词3天表现（平均值）
     * @param int $maxPrice 当前关键词在当前模式下的最高出价（分）
     * @return AutoDriveV2Model 
     */
    protected function _evaluatePrice($keyword, &$autoLog, $stat3Day, $tbStat3Day, $changePrice, $maxPrice) {
    	$price = $stat3Day['click'] > 0 ? $stat3Day['cpc']*100 : $keyword['max_price'];
    	$dp = $this->_driveParams;

    	// 如果当前出价高于当前模式的最高限价
    	if($price > $maxPrice) {
//     		// 如果减价的目标出价低于最大允许价，正常减价
//     		if(!$autoLog['action'] && substr($autoLog['action'], -1) == AutoMaintainLogActions::DEC_PRICE
//     				&& $keyword['max_price'] - $changePrice < $maxPrice) 
//     			$autoLog['action'] = '0601' . AutoMaintainLogActions::DEC_PRICE;
//     		// 否则只涨至最高允许出价
//     		else
//     			$autoLog['action'] = '0601' . AutoMaintainLogActions::DEC_PRICE_TO_MAX_ALLOWED;

			// 降至最高限价
    		if(!$autoLog['action'] || substr($autoLog['action'], -1) != AutoMaintainLogActions::DEC_PRICE
    				|| $keyword['max_price'] - $changePrice > $maxPrice)
    			$autoLog['action'] = '0601' . AutoMaintainLogActions::DEC_PRICE_TO_MAX_ALLOWED;
    		
    	// 价格很高, 中低qscore. 其实已经基本上在_evaluateCtr()和_evaluatePv()中进行过判断了。
    	} else if($this->_checkPrice($keyword, self::HIGH_PRICE) && $keyword['qscore'] <= $dp['midQscore']) {
    		// 还是没有点击
    		if($stat3Day['click'] == 0) {
    			$autoLog['action'] = '0602' . AutoMaintainLogActions::DEC_PRICE;
    		// 甚至没有PV
    		} elseif($stat3Day['pv'] < $dp['absXLowPv'] && $stat3Day['ctr'] < $dp['lowCtrRatio'] * $tbStat3Day['ctr']) {
    			$autoLog['action'] = '0603' . AutoMaintainLogActions::DEC_PRICE;
    		}
    		
    	}
    	return $this;
    }
}
